package com.xxx.bluetooth;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothGattServerCallback;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.util.Log;

import java.util.UUID;

/**
 * @author hdz
 */
public class BleServerService extends Service {
    private static final String TAG = "BleServerService";
    private static final UUID UUID_CHARACTERISTIC_READ = UUID.fromString("0000FEEA-0000-1000-8000-00805F9B34FB");
    private static final UUID UUID_DESCRIPTOR = UUID.fromString("0000FEEB-0000-1000-8000-00805F9B34FB");;
    private BluetoothManager mBluetoothManager;
    private BluetoothGattServer mBluetoothGattServer;
    private BluetoothGattService mBluetoothGattService;
    private BluetoothDevice mBluetoothDevice;
    private BleStateListener mBleStateListener;

    private static final UUID SERVICE_UUID = UUID.fromString("0000FEE0-0000-1000-8000-00805F9B34FB");
    private static final UUID CHARACTERISTIC_UUID = UUID.fromString("0000FEE1-0000-1000-8000-00805F9B34FB");



    private BluetoothGattServerCallback mBluetoothGattServerCallback = new BluetoothGattServerCallback() {
        @Override
        public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
            super.onConnectionStateChange(device, status, newState);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                String devName = device.getName();
                String devAddr = device.getAddress();
                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    if (mBleStateListener != null) {
                        mBleStateListener.onConnectionStateChange(true, devName, devAddr);
                    }
                } else {
                    mBleStateListener.onConnectionStateChange(false, devName, devAddr);
                }
            }
        }

        @Override
        public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
            Log.d(TAG, "onCharacteristicReadRequest===="+device.getName() + " " + device.getAddress());
            Log.d(TAG, "onCharacteristicReadRequest===="+requestId);
            Log.d(TAG, "onCharacteristicReadRequest===="+offset);
            Log.d(TAG, "onCharacteristicReadRequest===="+characteristic);
            mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, characteristic.getValue());
        }

        @Override
        public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
            super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
            Log.d(TAG, "onCharacteristicWriteRequest===="+device.getName() + " " + device.getAddress());
            Log.d(TAG, "onCharacteristicWriteRequest===="+requestId);
            Log.d(TAG, "onCharacteristicWriteRequest===="+characteristic.getUuid());
            Log.d(TAG, "onCharacteristicWriteRequest===="+characteristic.getStringValue(offset));
            Log.d(TAG, "onCharacteristicWriteRequest===="+preparedWrite);
            Log.d(TAG, "onCharacteristicWriteRequest===="+responseNeeded);
            Log.d(TAG, "onCharacteristicWriteRequest===="+offset);
            Log.e(TAG, new String(value));

            mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);


            String str = new String(value) + " hello>";
            characteristic.setValue(str.getBytes());
            mBluetoothGattServer.notifyCharacteristicChanged(device, characteristic, false);
        }

        @Override
        public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
            super.onDescriptorReadRequest(device, requestId, offset, descriptor);
            Log.d(TAG, "onDescriptorReadRequest====");
        }

        @Override
        public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
            super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);
            Log.d(TAG, "onDescriptorWriteRequest====");
            Log.e(TAG, new String(value));
        }

        @Override
        public void onServiceAdded(int status, BluetoothGattService service) {
            super.onServiceAdded(status, service);
        }

        @Override
        public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
            super.onExecuteWrite(device, requestId, execute);
            Log.d(TAG, "onExecuteWrite===="+device.getName() + " " + device.getAddress());
            Log.d(TAG, "onExecuteWrite===="+requestId);
            Log.d(TAG, "onExecuteWrite===="+execute);
        }

        @Override
        public void onNotificationSent(BluetoothDevice device, int status) {
            super.onNotificationSent(device, status);
        }

        @Override
        public void onMtuChanged(BluetoothDevice device, int mtu) {
            super.onMtuChanged(device, mtu);
        }

        @Override
        public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
            super.onPhyUpdate(device, txPhy, rxPhy, status);
        }

        @Override
        public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
            super.onPhyRead(device, txPhy, rxPhy, status);
        }
    };



    public BleServerService() {
    }

    class InnerBinder extends Binder implements IServiceControl {
        @Override
        public void setBleStateListener(BleStateListener listener) {
            mBleStateListener = listener;
        }
    }


    @Override
    public IBinder onBind(Intent intent) {
        return new InnerBinder();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("==", "启动===");
        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);


        initGattServer();


    }


    private void initGattServer() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            AdvertiseSettings settings = new AdvertiseSettings.Builder().setConnectable(true).build();
            AdvertiseData advertiseData = new AdvertiseData.Builder().setIncludeDeviceName(true).setIncludeTxPowerLevel(true).build();
            AdvertiseData scanResponseData = new AdvertiseData.Builder().addServiceUuid(new ParcelUuid(SERVICE_UUID)).setIncludeTxPowerLevel(true).build();

            AdvertiseCallback callback = new AdvertiseCallback() {
                @Override
                public void onStartSuccess(AdvertiseSettings settingsInEffect) {
                    super.onStartSuccess(settingsInEffect);
                    initService(BleServerService.this);
                }

                @Override
                public void onStartFailure(int errorCode) {
                    super.onStartFailure(errorCode);
                }
            };
            BluetoothLeAdvertiser bluetoothLeAdvertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
            if (bluetoothLeAdvertiser != null) {
                bluetoothLeAdvertiser.startAdvertising(settings, advertiseData, scanResponseData, callback);
            }
        }
    }

    private void initService(Context context) {
        //创建GattServer服务器
        mBluetoothGattServer = mBluetoothManager.openGattServer(context, mBluetoothGattServerCallback);
        //创建指定UUID的服务
        BluetoothGattService service = new BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY);

        //创建可读可写的characteristic
        BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(CHARACTERISTIC_UUID,
                BluetoothGattCharacteristic.PROPERTY_READ|BluetoothGattCharacteristic.PROPERTY_WRITE|BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                BluetoothGattCharacteristic.PERMISSION_WRITE|BluetoothGattCharacteristic.PERMISSION_READ);

        service.addCharacteristic(characteristic);
        mBluetoothGattServer.addService(service);
    }

    public interface BleStateListener {
        void onConnectionStateChange(boolean bConnected, String devName, String devAddr);
    }

    public interface IServiceControl {
        void setBleStateListener(BleStateListener listener);
    }

}
